import * as Cesium from 'cesium';

export class DataSourse {
  constructor(cesiumManager) {
    this.cesiumManager = cesiumManager;
    this.dataSources = new Map(); // 存储已加载的数据源
  }

  /**
   * 加载GeoJSON数据
   * @param {String} name - 数据源名称
   * @param {String|Object} data - GeoJSON数据或URL
   * @param {Object} options - 加载选项
   * @returns {Promise<DataSource>} 返回加载的数据源
   */
  async loadGeoJson(name, data, options = {}) {
    if (!this.cesiumManager || !this.cesiumManager.viewer) {
      throw new Error('Cesium manager or viewer is not initialized');
    }

    try {
      const dataSource = new Cesium.GeoJsonDataSource();
      
      if (typeof data === 'string') {
        await dataSource.load(data, options);
      } else {
        await dataSource.load(data, options);
      }
      
      this.cesiumManager.viewer.dataSources.add(dataSource);
      this.dataSources.set(name, dataSource);
      
      return dataSource;
    } catch (error) {
      console.error(`Failed to load GeoJSON data source "${name}":`, error);
      throw error;
    }
  }

  /**
   * 加载KML数据
   * @param {String} name - 数据源名称
   * @param {String|Document} data - KML数据或URL
   * @param {Object} options - 加载选项
   * @returns {Promise<DataSource>} 返回加载的数据源
   */
  async loadKml(name, data, options = {}) {
    if (!this.cesiumManager || !this.cesiumManager.viewer) {
      throw new Error('Cesium manager or viewer is not initialized');
    }

    try {
      const dataSource = new Cesium.KmlDataSource();
      
      if (typeof data === 'string') {
        await dataSource.load(data, options);
      } else {
        await dataSource.load(data, options);
      }
      
      this.cesiumManager.viewer.dataSources.add(dataSource);
      this.dataSources.set(name, dataSource);
      
      return dataSource;
    } catch (error) {
      console.error(`Failed to load KML data source "${name}":`, error);
      throw error;
    }
  }

  /**
   * 加载CZML数据
   * @param {String} name - 数据源名称
   * @param {String|Array|Document} data - CZML数据或URL
   * @param {Object} options - 加载选项
   * @returns {Promise<DataSource>} 返回加载的数据源
   */
  async loadCzml(name, data, options = {}) {
    if (!this.cesiumManager || !this.cesiumManager.viewer) {
      throw new Error('Cesium manager or viewer is not initialized');
    }

    try {
      const dataSource = new Cesium.CzmlDataSource();
      
      if (typeof data === 'string') {
        await dataSource.load(data, options);
      } else {
        await dataSource.load(data, options);
      }
      
      this.cesiumManager.viewer.dataSources.add(dataSource);
      this.dataSources.set(name, dataSource);
      
      return dataSource;
    } catch (error) {
      console.error(`Failed to load CZML data source "${name}":`, error);
      throw error;
    }
  }

  /**
   * 加载GPX数据
   * @param {String} name - 数据源名称
   * @param {String|Document} data - GPX数据或URL
   * @param {Object} options - 加载选项
   * @returns {Promise<DataSource>} 返回加载的数据源
   */
  async loadGpx(name, data, options = {}) {
    if (!this.cesiumManager || !this.cesiumManager.viewer) {
      throw new Error('Cesium manager or viewer is not initialized');
    }

    try {
      const dataSource = new Cesium.GpxDataSource();
      
      if (typeof data === 'string') {
        await dataSource.load(data, options);
      } else {
        await dataSource.load(data, options);
      }
      
      this.cesiumManager.viewer.dataSources.add(dataSource);
      this.dataSources.set(name, dataSource);
      
      return dataSource;
    } catch (error) {
      console.error(`Failed to load GPX data source "${name}":`, error);
      throw error;
    }
  }

  /**
   * 获取数据源
   * @param {String} name - 数据源名称
   * @returns {DataSource|undefined} 数据源对象
   */
  getDataSource(name) {
    return this.dataSources.get(name);
  }

  /**
   * 移除数据源
   * @param {String} name - 数据源名称
   */
  async removeDataSource(name) {
    const dataSource = this.dataSources.get(name);
    if (dataSource) {
      if (this.cesiumManager && this.cesiumManager.viewer) {
        await this.cesiumManager.viewer.dataSources.remove(dataSource);
      }
      this.dataSources.delete(name);
    }
  }

  /**
   * 更新数据源选项
   * @param {String} name - 数据源名称
   * @param {Object} options - 更新选项
   */
  updateDataSource(name, options) {
    const dataSource = this.dataSources.get(name);
    if (!dataSource) {
      throw new Error(`Data source "${name}" not found`);
    }

    // 更新数据源的通用属性
    if (options.show !== undefined) {
      dataSource.show = options.show;
    }
    
    // 对于特定类型的数据源，可以添加更多定制选项
    if (options.entityOptions && dataSource.entities) {
      dataSource.entities.values.forEach(entity => {
        // 更新实体样式等属性
        if (options.entityOptions.point && entity.point) {
          Object.assign(entity.point, options.entityOptions.point);
        }
        if (options.entityOptions.billboard && entity.billboard) {
          Object.assign(entity.billboard, options.entityOptions.billboard);
        }
        if (options.entityOptions.label && entity.label) {
          Object.assign(entity.label, options.entityOptions.label);
        }
        if (options.entityOptions.polyline && entity.polyline) {
          Object.assign(entity.polyline, options.entityOptions.polyline);
        }
        if (options.entityOptions.polygon && entity.polygon) {
          Object.assign(entity.polygon, options.entityOptions.polygon);
        }
      });
    }
  }

  /**
   * 获取所有数据源
   * @returns {Array} 所有数据源数组
   */
  getAllDataSources() {
    return Array.from(this.dataSources.values());
  }

  /**
   * 清除所有数据源
   */
  async clearAllDataSources() {
    if (this.cesiumManager && this.cesiumManager.viewer) {
      await this.cesiumManager.viewer.dataSources.removeAll();
    }
    this.dataSources.clear();
  }

  /**
   * 查询数据源中的实体
   * @param {String} dataSourceName - 数据源名称
   * @param {Function} filter - 过滤函数
   * @returns {Array} 符合条件的实体数组
   */
  queryEntities(dataSourceName, filter) {
    const dataSource = this.dataSources.get(dataSourceName);
    if (!dataSource) {
      throw new Error(`Data source "${dataSourceName}" not found`);
    }

    return dataSource.entities.values.filter(filter);
  }

  /**
   * 高亮指定实体
   * @param {Entity} entity - 要高亮的实体
   * @param {Object} highlightOptions - 高亮选项
   */
  highlightEntity(entity, highlightOptions = {}) {
    if (!entity) return;

    const defaultHighlight = {
      color: Cesium.Color.YELLOW,
      outlineColor: Cesium.Color.RED,
      scale: 1.5
    };

    const options = { ...defaultHighlight, ...highlightOptions };

    // 保存原始属性以便恢复
    if (!entity._originalProperties) {
      entity._originalProperties = {};
    }

    // 高亮点实体
    if (entity.point) {
      entity._originalProperties.point = {
        color: entity.point.color?.getValue() || entity.point.color,
        outlineColor: entity.point.outlineColor?.getValue() || entity.point.outlineColor,
        pixelSize: entity.point.pixelSize?.getValue() || entity.point.pixelSize
      };
      
      entity.point.color = options.color;
      entity.point.outlineColor = options.outlineColor;
      entity.point.pixelSize = (entity._originalProperties.point.pixelSize || 10) * options.scale;
    }

    // 高亮布告板实体
    if (entity.billboard) {
      entity._originalProperties.billboard = {
        color: entity.billboard.color?.getValue() || entity.billboard.color,
        scale: entity.billboard.scale?.getValue() || entity.billboard.scale
      };
      
      entity.billboard.color = options.color.withAlpha(
        entity.billboard.color?.getValue()?.alpha || 
        entity.billboard.color?.alpha || 
        1.0
      );
      entity.billboard.scale = (entity._originalProperties.billboard.scale || 1) * options.scale;
    }

    // 高亮多边形实体
    if (entity.polygon) {
      entity._originalProperties.polygon = {
        material: entity.polygon.material?.getValue() || entity.polygon.material,
        outlineColor: entity.polygon.outlineColor?.getValue() || entity.polygon.outlineColor
      };
      
      entity.polygon.material = options.color;
      entity.polygon.outlineColor = options.outlineColor;
    }

    // 高亮折线实体
    if (entity.polyline) {
      entity._originalProperties.polyline = {
        material: entity.polyline.material?.getValue() || entity.polyline.material,
        width: entity.polyline.width?.getValue() || entity.polyline.width
      };
      
      entity.polyline.material = options.color;
      entity.polyline.width = (entity._originalProperties.polyline.width || 1) * options.scale;
    }
  }

  /**
   * 取消高亮实体
   * @param {Entity} entity - 要取消高亮的实体
   */
  unhighlightEntity(entity) {
    if (!entity || !entity._originalProperties) return;

    // 恢复点实体原始属性
    if (entity.point && entity._originalProperties.point) {
      Object.assign(entity.point, entity._originalProperties.point);
    }

    // 恢复布告板实体原始属性
    if (entity.billboard && entity._originalProperties.billboard) {
      Object.assign(entity.billboard, entity._originalProperties.billboard);
    }

    // 恢复多边形实体原始属性
    if (entity.polygon && entity._originalProperties.polygon) {
      Object.assign(entity.polygon, entity._originalProperties.polygon);
    }

    // 恢复折线实体原始属性
    if (entity.polyline && entity._originalProperties.polyline) {
      Object.assign(entity.polyline, entity._originalProperties.polyline);
    }

    // 清除保存的原始属性
    delete entity._originalProperties;
  }

  /**
   * 销毁数据源管理器
   */
  destroy() {
    // 清理所有数据源
    this.clearAllDataSources();
    this.dataSources = null;
  }
}